K8s 內有一個 controller 叫做 PDB(Pod Disruption Budget),目的是要用来保證 Cluster 中始终有指定的 Pod replicas 處於可用狀態。藉由 PDB 可以設置處於運行狀態的 pod 最低個數或最低百分比,這樣可以保證在主動銷毀 pod 時,不會一次性關閉太多的 pod,從而保證 Service 的運作。聽起來是不是跟昨天的狀況很耳熟,我們昨天一直遇到砍不掉 POD 的問題就是因為有 PDB 阻擋。所以我們的解法便是移除 PDB 後,重新部署,但因為 PDB 還是得要留著,所以我們先備份 policy,以便之後還原
$ kubectl get pdb -n kube-system cluster-autoscaler-aws-cluster-autoscaler -o yaml > cluster-autoscaler.yaml
$ kubectl delete pdb -n kube-system cluster-autoscaler-aws-cluster-autoscaler
poddisruptionbudget.policy "cluster-autoscaler-aws-cluster-autoscaler" deleted
部署後可以看到 1.23 逐漸被套換成 1.24
$ kubectl get nodes -o wide -w
NAME STATUS ROLES AGE VERSION
ip-1 Ready <none> 13m v1.24.11-eks-a59e1f0
ip-2 Ready,SchedulingDisabled <none> 157m v1.23.17-eks-a59e1f0
ip-3 Ready <none> 13m v1.24.11-eks-a59e1f0
ip-4 Ready,SchedulingDisabled <none> 158m v1.23.17-eks-a59e1f0
進行還原
$ kubectl apply -f cluster-autoscaler.yaml
poddisruptionbudget.policy/cluster-autoscaler-aws-cluster-autoscaler created
那時候因為急著上版,先把移除的問題強制處理掉,但此時 Cluster AutoScaler 還是掛掉的狀況 ,我們回來追查原因
萬事不絕先查 logs,由於當時是 Cluster AutoScaler Pod 卡在 CrashLoopBack,所以查了此 pod logs 發現權限問題
F0420 03:20:37.080508 1 aws_cloud_provider.go:386] Failed to generate AWS EC2 Instance Types: UnauthorizedOperation: You are not authorized to perform this operation.
status code: 403, request id: 0a9bfb63-92ba-4454-a176-ac0907a3e52f
接著透過命令檢查 Cluster AutoScaler 所使用的 service account,其中並沒有指定 IAM Role,說明先前的 Cluster AutoScaler 是繼承 Worker Node 上的 IAM Role 權限。
$ kubectl describe sa cluster-autoscaler -n kube-system
Name: cluster-autoscaler
Namespace: kube-system
Labels: app.kubernetes.io/instance=cluster-autoscaler
app.kubernetes.io/managed-by=eksctl
app.kubernetes.io/name=aws-cluster-autoscaler
helm.sh/chart=cluster-autoscaler-9.27.0
Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::005791594643:role/xxxxxx
meta.helm.sh/release-name: cluster-autoscaler
meta.helm.sh/release-namespace: kube-system
Image pull secrets: <none>
Mountable secrets: cluster-autoscaler-token-6s5nq
Tokens: cluster-autoscaler-token-6s5nq
Events: <none>
為 Cluster AutoScaler 綁定 IAM Role,接著透過 eksctl 創建對應的 IAM Policy 與 IAM Role 並寫入至 Cluster AutoScaler 所使用的 service account 後,再次重跑 Cluster AutoScaler 的 Pod 後,最終恢復正常
eksctl create iamserviceaccount \
--cluster=xxxx \
--namespace=kube-system \
--name=cluster-autoscaler \
--attach-policy-arn=arn:aws:iam::xxx:policy/AmazonEKSClusterAutoscalerPolicy \
--override-existing-serviceaccounts \
--approve
實際上 Cluster AutoScaler Pod 是有繼承到 EKS Worker Node 上的 IAM Role,問題在於 Worker Node 的 IAM Role 缺少了 Cluster AutoScaler 所需要的權限,因此當時 Pod 才無法正常運行並返回與權限有關的錯誤。 而這個問題可能是從 helm CA 9.9.2 升級至 9.27.0 有關